package com.qdxht.dispenser.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Binder;
import android.os.IBinder;
import android.provider.Settings;

import androidx.annotation.Nullable;

import com.qdxht.dispenser.ui.models.entity.ConfigEntity;
import com.qdxht.dispenser.utils.ConfigUtil;
import com.qdxht.dispenser.utils.DeviceIdUtil;
import com.qdxht.dispenser.utils.MqttUtil;

import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import timber.log.Timber;

/**
 * MQTT管理服务
 * 负责MQTT连接管理、消息发布和订阅等功能
 */
public class MqttManagerService extends Service {
    
    private static final String TAG = "MqttManagerService";

    /**
     * 上报库存信息
     */
    public static final String TOPIC_INVENTORY = "device/upload/inventory";
    public static final String TOPIC_RESPONSE = "device/upload/response";
    public static final String TOPIC_OFFLINE = "device/upload/offline";
    public static final String TOPIC_INVENTORYALARM = "device/upload/inventoryAlarm";
    public static final String TOPIC_GPSINFO = "device/upload/gpsInfo";
    public static final String TOPIC_GPSALARM = "device/upload/gpsAlarm";
    public static final String TOPIC_STATUS = "device/upload/status";
    // 广告计数上报主题
    public static final String TOPIC_AD_PLAY_COUNT = "device/upload/adPlayCount";
    public static final String TOPIC_UPDATE_COMPLETED = "device/upload/updateCompleted";

    // MQTT服务器地址，应从配置中获取
    private String serverUri; // 默认使用公共MQTT服务器测试
    private String clientId;
    private String username;
    private String password;
    private MqttAndroidClient mqttClient;
    private final IBinder binder = new MqttBinder();
    private boolean autoReconnect = true;
    
    private final List<MqttEventCallback> eventCallbacks = new ArrayList<>();

    @Override
    public void onCreate() {
        super.onCreate();
        Timber.tag(TAG).i("MQTT Manager Service created");
        ConfigEntity config = ConfigUtil.getConfig();
        if (config != null) {
            serverUri = "tcp://" + config.getMqttIp() + ":" + config.getMqttPort();
            username = config.getMqttUserName();
            password = config.getMqttPassword();
            clientId = DeviceIdUtil.getAndroidId(this);
        }
        initMqttClient();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Timber.tag(TAG).i("MQTT Manager Service started");
        return START_STICKY; // 服务被杀死后自动重启
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    @Override
    public void onDestroy() {
        disconnectMqtt();
        super.onDestroy();
        Timber.tag(TAG).i("MQTT Manager Service destroyed");
    }

    /**
     * 初始化MQTT客户端
     */
    private void initMqttClient() {
        mqttClient = new MqttAndroidClient(getApplicationContext(), serverUri, clientId);
        mqttClient.setCallback(new MqttCallbackExtended() {
            @Override
            public void connectComplete(boolean reconnect, String serverURI) {
                Timber.tag(TAG).i("Connection complete to %s. Reconnect=%s", serverURI, reconnect);
                // 通知所有回调
                for (MqttEventCallback callback : eventCallbacks) {
                    callback.onConnectComplete(reconnect, serverURI);
                }
            }

            @Override
            public void connectionLost(Throwable cause) {
                Timber.tag(TAG).w(cause, "Connection lost");
                // 通知所有回调
                for (MqttEventCallback callback : eventCallbacks) {
                    callback.onConnectionLost(cause);
                }
                
                // 如果设置了自动重连，尝试重新连接
                if (autoReconnect && isNetworkAvailable()) {
                    Timber.tag(TAG).i("Attempting to reconnect...");
                    connectToMqttBroker();
                }
            }

            @Override
            public void messageArrived(String topic, MqttMessage message) throws Exception {
                String payload = new String(message.getPayload());
                Timber.tag(TAG).d("Message arrived on topic: %s, payload: %s", topic, payload);
                // 通知所有回调
                for (MqttEventCallback callback : eventCallbacks) {
                    callback.onMessageArrived(topic, message);
                }
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {
                Timber.tag(TAG).d("Message delivery complete");
                // 通知所有回调
                for (MqttEventCallback callback : eventCallbacks) {
                    callback.onDeliveryComplete(token);
                }
            }
        });
    }

    private String getMqttWill() {
        try {
            JSONObject resp = new JSONObject();
            resp.put("mainboardCode", DeviceIdUtil.getDeviceId(this));
            resp.put("uuid", DeviceIdUtil.getUUID());
            return resp.toString();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 连接到MQTT服务器
     * @return 是否成功发起连接请求
     */
    public boolean connectToMqttBroker() {
        try {
            if (mqttClient == null) {
                Timber.tag(TAG).e("Client not initialized，客户端异常无法连接！");
                return false;
            }

            if (!isNetworkAvailable()) {
                Timber.tag(TAG).e("no network connection, 网络异常无法连接！");
                return false;
            }

            if (mqttClient.isConnected()) {
                Timber.tag(TAG).d("Already connected to MQTT broker，已连接到MQTT代理！");
                return true;
            }

            MqttConnectOptions options = new MqttConnectOptions();
            options.setAutomaticReconnect(false);
            options.setCleanSession(false);
            
            // 设置认证信息（如果有）
            if (username != null && !username.isEmpty()) {
                options.setUserName(username);
            }
            if (password != null && !password.isEmpty()) {
                options.setPassword(password.toCharArray());
            }
            
            // 设置遗嘱消息
            options.setWill(TOPIC_OFFLINE, getMqttWill().getBytes(), 2, true);
            
            Timber.tag(TAG).i("Connecting to MQTT broker at %s...", serverUri);
            
            mqttClient.connect(options, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Timber.tag(TAG).i("Connected to MQTT broker");
                    
                    // 配置断开连接的缓冲选项
                    DisconnectedBufferOptions bufferOptions = new DisconnectedBufferOptions();
                    bufferOptions.setBufferEnabled(true);
                    bufferOptions.setBufferSize(100);
                    bufferOptions.setPersistBuffer(false);
                    bufferOptions.setDeleteOldestMessages(false);
                    mqttClient.setBufferOpts(bufferOptions);
                    // 通知连接成功
                    for (MqttEventCallback callback : eventCallbacks) {
                        callback.onConnectSuccess();
                    }
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Timber.tag(TAG).e(exception, "Failed to connect to MQTT broker");
                    // 通知连接失败
                    for (MqttEventCallback callback : eventCallbacks) {
                        callback.onConnectFailure(exception);
                    }
                }
            });
            return true;
        } catch (MqttException e) {
            Timber.tag(TAG).e(e, "Error connecting to MQTT broker");
            return false;
        }
    }
    
    /**
     * 断开与MQTT服务器的连接
     */
    public void disconnectMqtt() {
        if (mqttClient != null && mqttClient.isConnected()) {
            try {
                mqttClient.disconnect();
                Timber.tag(TAG).i("Disconnected from MQTT broker");
            } catch (MqttException e) {
                Timber.tag(TAG).e(e, "Error disconnecting from MQTT broker");
            }
        }
    }
    
    /**
     * 订阅主题
     * @param topic 主题名称
     * @param qos 服务质量 (0, 1, 2)
     * @return 是否成功发起订阅请求
     */
    public boolean subscribe(String topic, int qos) {
        if (mqttClient == null || !mqttClient.isConnected()) {
            Timber.tag(TAG).e("Cannot subscribe: Client not connected");
            return false;
        }
        
        try {
            mqttClient.subscribe(topic, qos, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Timber.tag(TAG).i("Subscribed to topic: %s", topic);
                    // 通知订阅成功
                    for (MqttEventCallback callback : eventCallbacks) {
                        callback.onSubscribeSuccess(topic);
                    }
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Timber.tag(TAG).e(exception, "Failed to subscribe to topic: %s", topic);
                    // 通知订阅失败
                    for (MqttEventCallback callback : eventCallbacks) {
                        callback.onSubscribeFailure(topic, exception);
                    }
                }
            });
            return true;
        } catch (MqttException e) {
            Timber.tag(TAG).e(e, "Error subscribing to topic: %s", topic);
            return false;
        }
    }
    
    /**
     * 订阅主题并设置消息监听器
     * @param topic 主题名称
     * @param qos 服务质量 (0, 1, 2)
     * @param messageListener 消息监听器
     * @return 是否成功发起订阅请求
     */
    public boolean subscribe(String topic, int qos, IMqttMessageListener messageListener) {
        if (mqttClient == null || !mqttClient.isConnected()) {
            Timber.tag(TAG).e("Cannot subscribe: Client not connected");
            return false;
        }
        
        try {
            mqttClient.subscribe(topic, qos, messageListener);
            Timber.tag(TAG).i("Subscribed to topic with listener: %s", topic);
            return true;
        } catch (MqttException e) {
            Timber.tag(TAG).e(e, "Error subscribing to topic with listener: %s", topic);
            return false;
        }
    }
    
    /**
     * 取消订阅主题
     * @param topic 主题名称
     * @return 是否成功发起取消订阅请求
     */
    public boolean unsubscribe(String topic) {
        if (mqttClient == null || !mqttClient.isConnected()) {
            Timber.tag(TAG).e("Cannot unsubscribe: Client not connected");
            return false;
        }
        
        try {
            mqttClient.unsubscribe(topic, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Timber.tag(TAG).i("Unsubscribed from topic: %s", topic);
                    // 通知取消订阅成功
                    for (MqttEventCallback callback : eventCallbacks) {
                        callback.onUnsubscribeSuccess(topic);
                    }
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Timber.tag(TAG).e(exception, "Failed to unsubscribe from topic: %s", topic);
                    // 通知取消订阅失败
                    for (MqttEventCallback callback : eventCallbacks) {
                        callback.onUnsubscribeFailure(topic, exception);
                    }
                }
            });
            return true;
        } catch (MqttException e) {
            Timber.tag(TAG).e(e, "Error unsubscribing from topic: %s", topic);
            return false;
        }
    }
    
    /**
     * 发布消息
     * @param topic 主题名称
     * @param payload 消息内容
     * @param qos 服务质量 (0, 1, 2)
     * @param retained 是否保留消息
     * @return 是否成功发起发布请求
     */
    public boolean publish(String topic, String payload, int qos, boolean retained) {
        if (mqttClient == null || !mqttClient.isConnected()) {
            Timber.tag(TAG).e("Cannot publish: Client not connected");
            return false;
        }
        
        try {
            MqttMessage message = new MqttMessage(payload.getBytes());
            message.setQos(qos);
            message.setRetained(retained);
            
            mqttClient.publish(topic, message, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Timber.tag(TAG).i("Published message to topic: %s", topic);
                    // 通知发布成功
                    for (MqttEventCallback callback : eventCallbacks) {
                        callback.onPublishSuccess(topic);
                    }
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Timber.tag(TAG).e(exception, "Failed to publish message to topic: %s", topic);
                    // 通知发布失败
                    for (MqttEventCallback callback : eventCallbacks) {
                        callback.onPublishFailure(topic, exception);
                    }
                }
            });
            return true;
        } catch (MqttException e) {
            Timber.tag(TAG).e(e, "Error publishing message to topic: %s", topic);
            return false;
        }
    }
    
    /**
     * 检查是否已连接到MQTT服务器
     * @return 是否已连接
     */
    public boolean isConnected() {
        return mqttClient != null && mqttClient.isConnected();
    }
    
    /**
     * 设置自动重连
     * @param autoReconnect 是否自动重连
     */
    public void setAutoReconnect(boolean autoReconnect) {
        this.autoReconnect = autoReconnect;
    }
    
    /**
     * 配置MQTT连接参数
     * @param serverUri 服务器地址
     * @param clientId 客户端ID
     * @param username 用户名
     * @param password 密码
     */
    public void configureMqtt(String serverUri, String clientId, String username, String password) {
        boolean needReconnect = this.serverUri != null && !this.serverUri.equals(serverUri) && isConnected();
        
        this.serverUri = serverUri;
        this.clientId = clientId;
        this.username = username;
        this.password = password;
        
        if (mqttClient != null && needReconnect) {
            disconnectMqtt();
            initMqttClient();
            if (autoReconnect) {
                connectToMqttBroker();
            }
        }
    }
    
    /**
     * 添加MQTT事件回调
     * @param callback 回调接口
     */
    public void addMqttEventCallback(MqttEventCallback callback) {
        if (callback != null && !eventCallbacks.contains(callback)) {
            eventCallbacks.add(callback);
        }
    }
    
    /**
     * 移除MQTT事件回调
     * @param callback 回调接口
     */
    public void removeMqttEventCallback(MqttEventCallback callback) {
        if (callback != null) {
            eventCallbacks.remove(callback);
        }
    }

    /**
     * 清空MQTT事件回调
     */
    public void clearMqttEventCallback() {
        eventCallbacks.clear();
    }


    /**
     * MQTT连接失败回调
     */
    public void onConnectFailure() {
        // 通知连接失败
        for (MqttEventCallback callback : eventCallbacks) {
            callback.onConnectFailure(new Exception("MQTT连接异常"));
        }
    }
    
    /**
     * 检查网络是否可用
     * @return 网络是否可用
     */
    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager = 
                (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivityManager != null) {
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            return activeNetworkInfo != null && activeNetworkInfo.isConnected();
        }
        return false;
    }
    
    /**
     * MQTT事件回调接口
     */
    public interface MqttEventCallback {
        // 连接相关
        void onConnectComplete(boolean reconnect, String serverURI);
        void onConnectSuccess();
        void onConnectFailure(Throwable cause);
        void onConnectionLost(Throwable cause);
        
        // 消息相关
        void onMessageArrived(String topic, MqttMessage message);
        void onDeliveryComplete(IMqttDeliveryToken token);
        
        // 订阅相关
        void onSubscribeSuccess(String topic);
        void onSubscribeFailure(String topic, Throwable cause);
        void onUnsubscribeSuccess(String topic);
        void onUnsubscribeFailure(String topic, Throwable cause);
        
        // 发布相关
        void onPublishSuccess(String topic);
        void onPublishFailure(String topic, Throwable cause);
    }
    
    /**
     * MQTT事件回调基础实现，可选择覆盖需要的方法
     */
    public static abstract class MqttEventCallbackAdapter implements MqttEventCallback {
        @Override
        public void onConnectComplete(boolean reconnect, String serverURI) {}
        
        @Override
        public void onConnectSuccess() {}
        
        @Override
        public void onConnectFailure(Throwable cause) {}
        
        @Override
        public void onConnectionLost(Throwable cause) {}
        
        @Override
        public void onMessageArrived(String topic, MqttMessage message) {}
        
        @Override
        public void onDeliveryComplete(IMqttDeliveryToken token) {}
        
        @Override
        public void onSubscribeSuccess(String topic) {}
        
        @Override
        public void onSubscribeFailure(String topic, Throwable cause) {}
        
        @Override
        public void onUnsubscribeSuccess(String topic) {}
        
        @Override
        public void onUnsubscribeFailure(String topic, Throwable cause) {}
        
        @Override
        public void onPublishSuccess(String topic) {}
        
        @Override
        public void onPublishFailure(String topic, Throwable cause) {}
    }
    
    /**
     * 绑定服务的Binder
     */
    public class MqttBinder extends Binder {
        public MqttManagerService getService() {
            return MqttManagerService.this;
        }
    }
} 